package com.bcx.crm.java.proxy.jdkProxy3;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;

/**
 * Created by ys on 2018/1/27.
 */
public class Test {
    /**
     *1.普通代理方式
     */
    public static void main1(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取动态代理类:com.sun.proxy.$Proxy0
        Class<?> proxyClass = Proxy.getProxyClass(ILook.class.getClassLoader(), ILook.class);
        //获取代理类的构造函数，并传入参数类型InvocationHandler
        Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
        //通过构造函数创建动态代理对象，并传入自定义的MyInvocationHandler
        ILook iLook =(ILook) constructor.newInstance(new MyInvocationHandler(new LookImpl()));
        //通过代理对象调用目标对象方法
        System.out.println("代理对象调用目标对象的返回值是:"+iLook.look("java经典"));
    }

    /**
     * 2.简便代理方式
     */
    public static void main2(String[] args) {
        ILook iLook=(ILook) Proxy.newProxyInstance(ILook.class.getClassLoader(), //加载接口的类加载器
                                                   new Class[]{ILook.class},     //一组接口
                                                   new MyInvocationHandler(new LookImpl()));    //自定义的InvocationHandler
        String javascript = iLook.look("javascript");
        System.out.println(javascript);
        String writeTool = iLook.write("毛笔");
        System.out.println(writeTool);
    }

    /**
     * 3.将代理类进行封装
     */
    public static void main(String[] args) {
        ILook iLook = Test.getILook();   //直接根据该方法获取代理类
        iLook.write("钢笔");
        iLook.look("数学");
    }

    /**
     *3.1将目标类类隐藏，对外提供代理类
     */
    private static ILook getILook(){
        return (ILook) Proxy.newProxyInstance(ILook.class.getClassLoader(),
                new Class[]{ILook.class},
                new MyInvocationHandler(new LookImpl()));
    }

}
